commonlibsse_ng\re\e/
ExtraTextDisplayData.rs

1//! # ExtraTextDisplayData
2//!
3//! Represents extra data for text display, including a name, temper factor, and owner quest.
4//!
5//! Inherits from `BSExtraData` and uses `BSFixedString` for display names.
6//!
7//! # Memory Layout:
8//! - `__base`: Base class `BSExtraData`
9//! - `display_name`: Display name string (0x10)
10//! - `display_name_text`: Pointer to `BGSMessage` (0x18)
11//! - `owner_quest`: Pointer to `TESQuest` (0x20)
12//! - `owner_instance`: Display data type (0x28)
13//! - `temper_factor`: Temper factor (0x2C)
14//! - `custom_name_length`: Length of the custom name (0x30)
15//! - `pad32`: Padding for alignment (0x32)
16//! - `pad34`: Padding for alignment (0x34)
17
18use crate::re::BGSMessage::BGSMessage;
19use crate::re::BSExtraData::{BSExtraData, DerivedBSExtraData};
20use crate::re::BSFixedString::BSFixedString;
21use crate::re::ExtraDataType::ExtraDataType;
22use crate::re::TESBoundObject::TESBoundObject;
23use crate::re::TESQuest::TESQuest;
24use crate::re::offsets_rtti::RTTI_ExtraTextDisplayData;
25use crate::re::offsets_vtable::VTABLE_ExtraTextDisplayData;
26use crate::rel::id::VariantID;
27use core::ffi::{CStr, c_char, c_float};
28use std::ptr;
29
30#[repr(C)]
31#[derive(Debug, PartialEq)]
32pub struct ExtraTextDisplayData {
33    /// Base class `BSExtraData`.
34    pub __base: BSExtraData,
35
36    /// Display name string.
37    /// Offset: `0x10`
38    pub display_name: BSFixedString,
39
40    /// Pointer to a `BGSMessage`.
41    /// Offset: `0x18`
42    pub display_name_text: *mut BGSMessage,
43
44    /// Pointer to the owner quest.
45    /// Offset: `0x20`
46    pub owner_quest: *mut TESQuest,
47
48    /// Display data type.
49    /// Offset: `0x28`
50    pub owner_instance: DisplayDataType,
51
52    /// Temper factor.
53    /// Offset: `0x2C`
54    pub temper_factor: f32,
55
56    /// Length of the custom name.
57    /// Offset: `0x30`
58    pub custom_name_length: u16,
59
60    /// Padding for alignment.
61    /// Offset: `0x32`
62    pub pad32: u16,
63
64    /// Padding for alignment.
65    /// Offset: `0x34`
66    pub pad34: u32,
67}
68
69const _: () = {
70    assert!(core::mem::offset_of!(ExtraTextDisplayData, __base) == 0x0);
71    assert!(core::mem::offset_of!(ExtraTextDisplayData, display_name) == 0x10);
72    assert!(core::mem::offset_of!(ExtraTextDisplayData, display_name_text) == 0x18);
73    assert!(core::mem::offset_of!(ExtraTextDisplayData, owner_quest) == 0x20);
74    assert!(core::mem::offset_of!(ExtraTextDisplayData, owner_instance) == 0x28);
75    assert!(core::mem::offset_of!(ExtraTextDisplayData, temper_factor) == 0x2C);
76    assert!(core::mem::offset_of!(ExtraTextDisplayData, custom_name_length) == 0x30);
77    assert!(core::mem::offset_of!(ExtraTextDisplayData, pad32) == 0x32);
78    assert!(core::mem::offset_of!(ExtraTextDisplayData, pad34) == 0x34);
79    assert!(core::mem::size_of::<ExtraTextDisplayData>() == 0x38);
80};
81
82impl Default for ExtraTextDisplayData {
83    #[inline]
84    fn default() -> Self {
85        Self::new()
86    }
87}
88
89impl DerivedBSExtraData for ExtraTextDisplayData {
90    #[inline]
91    fn get_extra_data(&self) -> &BSExtraData {
92        &self.__base
93    }
94
95    #[inline]
96    fn get_extra_data_type() -> ExtraDataType {
97        Self::EXTRA_DATA_TYPE
98    }
99}
100
101impl ExtraTextDisplayData {
102    /// Address & offset of the runtime type information (RTTI) identifier.
103    pub const RTTI: VariantID = RTTI_ExtraTextDisplayData;
104
105    /// Address & offset of the virtual function table.
106    pub const VTABLE: [VariantID; 1] = VTABLE_ExtraTextDisplayData;
107
108    /// The `ExtraDataType` value for text display data.
109    pub const EXTRA_DATA_TYPE: ExtraDataType = ExtraDataType::TextDisplayData;
110
111    /// Creates a new `ExtraTextDisplayData` instance with default values.
112    #[inline]
113    pub const fn new() -> Self {
114        Self {
115            __base: BSExtraData::new(),
116            display_name: BSFixedString::DEFAULT,
117            display_name_text: ptr::null_mut(),
118            owner_quest: ptr::null_mut(),
119            owner_instance: DisplayDataType::Uninitialized,
120            temper_factor: 1.0,
121            custom_name_length: 0,
122            pad32: 0,
123            pad34: 0,
124        }
125    }
126
127    /// Creates a new `ExtraTextDisplayData` instance with a specified name.
128    #[inline]
129    pub fn from_name(name: &CStr) -> Self {
130        let mut instance = Self::new();
131        instance.set_name(name);
132        instance
133    }
134
135    /// Creates a new `ExtraTextDisplayData` with a form and temper factor.
136    /// # Safety
137    /// form is a valid ptr.
138    #[inline]
139    pub unsafe fn from_form(form: *mut TESBoundObject, temper_factor: f32) -> Self {
140        let mut instance = Self::new();
141        unsafe { instance.get_display_name(form, temper_factor) };
142        instance
143    }
144
145    /// Gets the extra data type, always returning `ExtraDataType::TextDisplayData`.
146    #[inline]
147    pub const fn get_type(&self) -> ExtraDataType {
148        ExtraDataType::TextDisplayData
149    }
150
151    /// Gets the display name based on the form and temper factor.
152    ///
153    /// - lifetime: `'a form` -> `'a c_char`
154    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 12626, ae_id = 12768)]
155    pub unsafe fn get_display_name(
156        &mut self,
157        form: *const TESBoundObject, // FIXME: maybe const?
158        temper_factor: c_float,
159    ) -> *const c_char {
160    }
161
162    /// Checks if the display data is player-set.
163    #[inline]
164    pub fn is_player_set(&self) -> bool {
165        self.owner_instance == DisplayDataType::CustomName
166    }
167
168    /// Sets the display name.
169    #[inline]
170    pub fn set_name(&mut self, name: &CStr) {
171        if !self.display_name_text.is_null() {
172            return;
173        }
174
175        self.display_name = BSFixedString::new(name);
176        self.custom_name_length = name.count_bytes() as u16;
177        self.owner_instance = DisplayDataType::CustomName;
178        self.temper_factor = 1.0;
179    }
180}
181
182bitflags::bitflags! {
183    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
184    pub struct DisplayDataType: i32 {
185        const Uninitialized = -1;
186        const CustomName = -2;
187    }
188}
189
190/// The virtual function table for `ExtraTextDisplayData`.
191///
192/// This struct defines function pointers to simulate the C++ virtual functions.
193#[repr(C)]
194#[derive(Debug)]
195pub struct ExtraTextDisplayDataVtbl {
196    /// Destructor function pointer.
197    pub CxxDrop: fn(this: &mut ExtraTextDisplayData),
198
199    /// Function pointer for retrieving the extra data type.
200    pub GetType: fn(this: &ExtraTextDisplayData) -> ExtraDataType,
201}
202
203impl Default for ExtraTextDisplayDataVtbl {
204    #[inline]
205    fn default() -> Self {
206        Self::new()
207    }
208}
209
210impl ExtraTextDisplayDataVtbl {
211    /// Creates a new default virtual table with stubbed functions.
212    pub const fn new() -> Self {
213        const fn CxxDrop(_this: &mut ExtraTextDisplayData) {}
214
215        const fn GetType(_this: &ExtraTextDisplayData) -> ExtraDataType {
216            ExtraTextDisplayData::EXTRA_DATA_TYPE
217        }
218
219        Self { CxxDrop, GetType }
220    }
221}